package main

import (
	"m3u8/info"
	"m3u8/input"
	"m3u8/util"
	"bytes"
	"fmt"
	"os/exec"
	"strconv"
	"strings"
	"sync"
	"time"
)

type InputInterface interface {
	Parse()
	SaveTs(i int, channel chan info.Info, downChan chan bool, wg *sync.WaitGroup)
	GetUrl() string
	GetCount() int
	GetTsNamePattern() string
	GetFiles() []string
	GetM3u8Name() string
	Dir() string
	Check()
	MaxConnection() int
	GetIndex() int
	RemoveFile()
}

var channel chan info.Info

func main() {
	var in, now = GetInput(), time.Now()
	in.Parse()
	var count = in.GetCount()
	fmt.Println("共有" + strconv.Itoa(count) + "个片段")
	time.Sleep(time.Second * 1)
	channel = make(chan info.Info)
	downChan := make(chan bool, in.MaxConnection())
	var wg sync.WaitGroup

	defer func() {
		close(channel)
		close(downChan)
	}()

	go printMsg(in)

	var i int
	for i = 1; i <= count; i++ {
		wg.Add(1)
		go in.SaveTs(i, channel, downChan, &wg)
	}

	wg.Wait()
	time.Sleep(time.Second / 2)
	in.Check()
	fmt.Println("下载完成，合并中...")

	files := strings.Join(in.GetFiles(), "|")
	outfile := in.Dir() + in.GetM3u8Name() + ".mp4"
	cmdExec := []string{"-i", "concat:" + files, "-c", "copy", outfile}
	fmt.Println(cmdExec)
	cmd := exec.Command("ffmpeg", cmdExec...)
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		fmt.Println("concat error", err.Error())
		return
	}
	in.RemoveFile()

	fmt.Println("总用时:" + util.HumanTime(now))
	fmt.Println("-----------------------------------------------")
	fmt.Println()
	fmt.Println(stdout.String(), stderr.String())
	fmt.Println("-----------------------------------------------END")
}

func GetInput() InputInterface {
	return &input.Simple{}
}

func printMsg(in InputInterface) {
	sucCount := 1
	for res := range channel {
		fmt.Println(fmt.Sprintf("(%d/%d/%d)", res.Num, in.GetCount(), in.GetCount()-sucCount), res.Msg)
		if !res.IsTry {
			sucCount++
		}
	}
}
